class Load {
  constructor() {
    /**
     * @type {Record<string, HTMLElement>}
     */
    this.dom = {
      progress: $('.load .progress'),
      bar: $('.load .bar'),
      text: $('.load .text')
    }
    this.enter()
  }

  async enter() {
    const { progress, bar, text } = this.dom
    await animate(3000, 0, 100, (val) => {
      bar.style.width = parseInt(val) + '%'
    })
    page.next()
  }
}

class Audio {
  constructor() {
    /**
     * @type {Record<string, HTMLElement>}
     */
    this.dom = {
      music: $('.music'),
      audio: $('.music audio'),
      icon: $('.music .icon')
    }
    this.bind()
  }
  
  bind() {
    const { icon, audio } = this.dom
    icon.onclick = () => {
      if (audio.paused) {
        audio.play()
        icon.classList.add('ani-rotate')
      } else {
        audio.pause()
        icon.classList.remove('ani-rotate')
      }
    }
  }

  showIcon() {
    const { icon } = this.dom
    icon.show()
  }
}

class P1 {
  constructor() {
    /**
     * @type {Record<string, HTMLElement>}
     */
    this.dom = {
      btn: $('.p1 .btn')
    }
    this.bind()
    this.enter()
  }
  
  bind() {
    const { btn } = this.dom
    btn.onclick = () => page.next()
  }
  
  enter() {
    new Audio().showIcon()
  }
}

function jumpAnimate() {
  const doms = $all('.title')
  doms.forEach(dom => {
    const texts = dom.innerText.split('')
    dom.innerText = ''
    texts.forEach((item, i) => {
      const span = document.createElement('span')
      span.innerText = item
      span.classList.add('ani-transY')
      span.style.animationDelay = 0.2 * i + 's'
      dom.appendChild(span)
    })
  })
}
jumpAnimate()

class P2 {
  constructor() {
    /**
     * @type {Record<string, HTMLElement>}
     */
    this.dom = {
      btn: $('.p2 .btn'),
      back: $('.p2 .back')
    }
    this.bind()
  }
  
  bind() {
    const { btn, back } = this.dom
    btn.onclick = () => page.next()
    back.onclick = () => page.prev()
  }
}

class P3 {
  constructor() {
    /**
     * @type {Record<string, HTMLElement | HTMLElement[]>}
     */
    this.dom = {
      btn: $('.p3 .btn'),
      back: $('.p3 .back'),
      items: $all('.p3 .list .item')
    }
    this.bind()
  }
  
  bind() {
    const { btn, back, items } = this.dom
    btn.onclick = () => this.submit()
    back.onclick = () => page.prev()
    items.forEach(item => {
      item.onclick = () => {
        item.classList.toggle('active')
      }
    })
  }
  
  submit() {
    window.state = [...$all('.p3 .item.active')].map(item => item.children[1].innerText)
    page.next()
  }
}

class P4 {
  constructor() {
    /**
     * @type {Record<string, HTMLElement | HTMLElement[]>}
     */
    this.dom = {
      btn: $('.p4 .btn'),
      back: $('.p4 .back'),
      list: $('.p4 .list'),
      items: $all('.p4 .list .item'),
      score: $('.p4 .score span'),
      stars: $all('.p4 .stars img')
    }
    this.state = window.state
    this.bind()
    this.render()
    this.renderList()
    this.renderStars()
  }
  
  bind() {
    const { btn, back } = this.dom
    btn.onclick = () => {
      page.next()
      this.reset()
    }
    back.onclick = () => {
      page.prev()
      this.reset()
    }
  }
  
  reset() {
    const { stars } = this.dom;
    [...stars].forEach((item, i) => {
      item.classList.remove('active')
    })
  }
  
  render() {
    const { score } = this.dom
    score.innerText = this.score
  }
  
  renderStars() {
    const { stars } = this.dom;
    [...stars].forEach((item, i) => {
      if (i <= Math.floor(this.score) - 1) {
        item.src = './img/p4/star-active.png'
      }
    })
    stars[0].style.transitionDelay = 0 + 's'
    stars[4].style.transitionDelay = 0.2 + 's'
    stars[1].style.transitionDelay = 0.4 + 's'
    stars[3].style.transitionDelay = 0.6 + 's'
    stars[2].style.transitionDelay = 0.8 + 's'
    requestAnimationFrame(() => {
      [...stars].forEach(item => {
        item.classList.add('active')
      })
    })
  }
  
  renderList() {
    const { list } = this.dom
    const statelist = this.state
    let html = ''
    statelist.forEach(item => {
      html += `<div class="item">${item}</div>`
    })
    list.innerHTML = html
  }
  
  get score() {
    return this.state.length * 0.5
  }
}

class P5 {
  constructor() {
    /**
     * @type {Record<string, HTMLElement | HTMLElement[]>}
     */
    this.dom = {
      btn: $('.p5 .btn'),
      back: $('.p5 .back'),
      zhengshu: $('.p5 .zhengshu')
    }
    this.bind()
    this.enter()
  }
  
  bind() {
    const { btn, back } = this.dom
    btn.onclick = () => page.goHome()
    back.onclick = () => page.prev()
  }
  
  enter() {
    const { zhengshu } = this.dom
    zhengshu.classList.add('active')
  }
}

class Page {
  constructor() {
    this.old = -1
    this.page = 0
    /**
     * @type {Record<string, HTMLElement>}
     */
    this.dom = {
      pages: $all('.page')
    }
    new Load()
  }

  change() {
    const { old, page, dom: { pages } } = this
    if (old === 0) {
      pages[old].hide()
    } else {
      pages[old].fadeOut()
      pages[page].fadeIn()
    }
    this.handleChange()
  }
  
  handleChange() {
    const { page } = this
    if (page === 1) new P1()
    if (page === 2) new P2()
    if (page === 3) new P3()
    if (page === 4) new P4()
    if (page === 5) new P5()
  }
  
  next() {
    this.old = this.page
    this.page++
    this.change()
  }
  
  prev() {
    this.old = this.page
    this.page--
    this.change()
  }
  
  goHome() {
    this.old = this.page
    this.page = 1
    this.change()
  }
}

const page = new Page()